package it.unina.loquendo;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.EOFException;
import java.io.RandomAccessFile;

import android.util.Log;
import com.loquendo.asr.*;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.MediaRecorder; //constants and params
import android.media.ToneGenerator;
import android.os.Environment;

public class BoardAudioSource implements ASRAudioSource
{
	private static final String LOGTAG = "BoardAudioSource";
    boolean m_bIsStopped;
    byte[] m_abyBuffer;
    int m_nMaxLength;

    static final int m_nSource = MediaRecorder.AudioSource.MIC;
    static final int m_nChannel = AudioFormat.CHANNEL_IN_MONO;
    static final int m_nFormat = AudioFormat.ENCODING_PCM_16BIT;
    static int m_nSampleRate = 16000; //44100, 8000

    AudioRecord m_oAudioRecord = null;


    public BoardAudioSource()
    {
        // default values

        m_bIsStopped = true;
        m_abyBuffer = null;
        m_nMaxLength = 4096;

        m_oAudioRecord = null;

    }
    
    public void SetSamplingFrequency(int sampleRate) {
    	m_nSampleRate = sampleRate;
    }

    public void Open()
    {
    }

    public void Close()
    {
        if(m_oAudioRecord != null) m_oAudioRecord.release();
    }

    public void Start()
    {
        Log.d(LOGTAG, "AudioStart START");
        try
        {
        	ToneGenerator beep = new ToneGenerator(AudioManager.STREAM_ALARM, 50);

            int nMinBufferSize = AudioRecord.getMinBufferSize(m_nSampleRate, m_nChannel, m_nFormat);
            if (nMinBufferSize != AudioRecord.ERROR && nMinBufferSize != AudioRecord.ERROR_BAD_VALUE)
            {
            m_nMaxLength = nMinBufferSize;
            m_oAudioRecord = new AudioRecord(m_nSource, m_nSampleRate, m_nChannel, m_nFormat, m_nMaxLength);
			beep.startTone(ToneGenerator.TONE_DTMF_0, 50);
			try {
					synchronized(this) {
   						wait(70);
   					}
			} catch (InterruptedException e) {
					e.printStackTrace();
			}
            m_oAudioRecord.startRecording();
            m_abyBuffer = new byte[m_nMaxLength];
            m_bIsStopped = false;
            }
        }
        catch (Exception oException)
        {
              Log.d(LOGTAG, "EXCEPTION");
        }
        Log.d(LOGTAG, "AudioStart END");
    }
    public void Stop()
    {
        Log.d(LOGTAG, "AudioStop START");
        if (!m_bIsStopped) {
        	m_oAudioRecord.stop();
            m_bIsStopped = true;
        }
        Log.d(LOGTAG, "AudioStop END");
    }
    public boolean IsStopped()
    {
        Log.d(LOGTAG, "AudioIsStopped START");
        Log.d(LOGTAG, "AudioIsStopped END");
        return m_bIsStopped;
    }
    public byte[] GetSampleBuffer()
    {
        byte[] abyBuffer = null;
        //Log.d(LOGTAG, "AudioGetSampleBuffer START");
        try
        {
            if (!m_bIsStopped)
            {
                  int nLength = m_oAudioRecord.read(m_abyBuffer, 0, m_nMaxLength);
                  Log.d(LOGTAG, "AudioGetSampleBuffer samples="+nLength);
                  if (nLength > 0 && nLength != AudioRecord.ERROR_INVALID_OPERATION && nLength != AudioRecord.ERROR_BAD_VALUE)
                  {
                    abyBuffer = new byte[nLength];
                    for (int nIdx = 0; nIdx < nLength; nIdx++)
                    {
                        abyBuffer[nIdx] = m_abyBuffer[nIdx];
                    }
                  }
            }
        }
        catch (Exception oException)
        {
              Log.d(LOGTAG, "EXCEPTION");
        }
        //Log.d(LOGTAG, "AudioGetSampleBuffer END");
        return abyBuffer;
    }
    
    protected void finalize() throws Throwable
    {
        if(m_oAudioRecord != null) m_oAudioRecord.release();
    	super.finalize(); 
    } 
}
